Skip to content

Switch C# to Roslyn and add build-then-debug - #17

Merged
SimonKimDev merged 1 commit into
mainfrom
simonk/dev/csharp-roslyn
Oct 19, 2026
Merged

SimonKimDev merged 1 commit into
mainfrom
simonk/dev/csharp-roslyn

Conversation

@SimonKimDev

Copy link
Copy Markdown
Owner

Switches C# from csharp-ls to Roslyn and makes debugging build first and pick the right project.

Language server

  • roslyn.nvim (needs Neovim 0.12) runs Roslyn, the server behind VS Code's C# extension: full analyzer/StyleCop diagnostics and code fixes, source generators, .slnx support, :Roslyn target to switch solutions.
  • Installed through Mason from Microsoft's roslyn-language-server package on nuget.org, pinned to 5.13.0-1.26514.10 (newer than VS Code's). Mason's registry default (5.12.0-1.26426.8) is older than roslyn.nvim's minimum, and I avoided the third-party registry the plugin suggests. The plugin update workflow won't bump this pin.
  • mason-lspconfig drops csharp_ls and excludes roslyn_ls / csharp_ls from automatic_enable, otherwise the Mason package (or a leftover csharp-ls install) would attach a second C# client.
  • Roslyn inlay hint settings so <leader>ih works for C#.

Debugging (lua/simonkdev/dotnet.lua): <leader>dc in a C# file → Build and debug a project

  • lists the solution's runnable projects (OutputType Exe/WinExe, Web/Worker SDK; all projects if none match), last pick first
  • for multi-target projects picks the newest .NET target, since netcoredbg can't debug .NET Framework (net472)
  • dotnet build; on failure the errors go to quickfix and no session starts
  • launches MSBuild's TargetPath with the project directory as cwd, like dotnet run
  • Hooked in as the coreclr adapter's enrich_config, so neotest's test debugging (also coreclr) is unchanged.

Tested locally on 0.12.6 with a throwaway .slnx (console app, net472;net10.0 console app, class library):

  • one roslyn client attached and selected the .slnx; cross-file go-to-definition, inlay hints, and format + trailing-whitespace trim all work
  • picker listed only the two apps and remembered the last pick; the multi-target app built for net10.0, stopped at a breakpoint, showed the stack and evaluated a local
  • a syntax error put 2 entries in quickfix and started no session
  • fresh smoke run passes

After merging, I'll pull it into your live config and uninstall the Mason csharp-language-server package.

- roslyn.nvim runs Roslyn, the server VS Code's C# extension uses,
  instead of csharp-ls. It's installed through Mason from Microsoft's
  nuget.org package, pinned because Mason's registry default is older
  than roslyn.nvim supports. Inlay hint settings keep <leader>ih working.
- mason-lspconfig no longer installs csharp_ls and excludes roslyn_ls
  and csharp_ls from automatic_enable, so only one C# client attaches
  (an existing csharp-ls install would otherwise still start).
- simonkdev/dotnet.lua replaces mason-nvim-dap's "pick any DLL under
  bin/Debug" config with "Build and debug a project": it lists the
  solution's runnable projects (last pick first), builds the chosen one
  for its newest .NET target (netcoredbg can't debug .NET Framework),
  sends build errors to quickfix, and launches the TargetPath MSBuild
  reports, with the project directory as cwd like `dotnet run`. It runs
  as the coreclr adapter's enrich_config, so neotest's test debugging
  is unaffected.
- Smoke test checks the roslyn client is enabled and roslyn_ls and
  csharp_ls are excluded.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 90315f97-7c82-4bc1-9bf1-2f8460782554
@SimonKimDev
SimonKimDev marked this pull request as ready for review October 19, 2026 05:18
@SimonKimDev
SimonKimDev merged commit 95d0217 into main Oct 19, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant